package com.example.community.controller;

import com.example.community.elasticsearch.DiscussPost2Repository;
import com.example.community.elasticsearch.DiscussPostRepository;
import com.example.community.entity.*;
import com.example.community.event.EventProducer;
import com.example.community.service.*;
import com.example.community.util.CommunityConstant;
import com.example.community.util.CommunityUitl;
import com.example.community.util.HostHolder;
import com.example.community.util.RedisKeyUtil;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import top.starp.util.ReturnT;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Stream;

@Controller
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {
    @Autowired
    private DiscussPostService discussPostService;
    @Autowired
    private UserService userService;
    @Autowired
    private HostHolder hostHolder;
    @Autowired
    private CommentService commentService;
    @Autowired
    private LikeService likeService;
    @Autowired
    private EventProducer eventProducer;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ElasticsearchRestTemplate elasticTemplate;
//    elasticTemplate 索引 用的哪个
    @GetMapping("/getSearch")
    @ResponseBody
    public Object getSearch(String name){
        //构建分页
        Pageable pageable= PageRequest.of(0,999);
        NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder();
        NativeSearchQuery query=builder.withQuery(QueryBuilders.queryStringQuery(name))
                .withPageable(pageable)
                .build();
        ElasticsearchRestTemplate elasticsearchRestTemplate;
        elasticsearchRestTemplate=elasticTemplate;
        SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(
                query, DiscussPost.class);
        Stream<SearchHit<DiscussPost>>
                searchHitStream = search.get();
        return searchHitStream;
    }

//-----------------------------------
//        ©著作权归作者所有：来自51CTO博客作者wx6316c4e40e2ec的原创作品，请联系作者获取转载授权，否则将追究法律责任
//    使用ElasticsearchRestTemplate.search
//    https://blog.51cto.com/u_15781933/5655026
//
    @PostMapping(path = "/save")
    @ResponseBody
    public Object save(@RequestBody  DiscussPost discussPost) {
//        final DiscussPost discussPost1 = new DiscussPost();
        discussPost.setCreateTime(new Date());
        final DiscussPost save = elasticTemplate.save(discussPost);
        return  ReturnT.success(save);
//        return CommunityUitl.getJSONString(0, "发布成功",save);
    }
    @Resource
    DiscussPostRepository discussPostRepository;

    /**
     * {
     *   "id": 1,
     *   "userId": 1,
     *   "title": "demoData",
     *   "content": "demoData",
     *   "type": 1,
     *   "status": 1,
     *   "createTime": null,
     *   "commentCount": 1,
     *   "score": 1.0
     * }
     * @param discussPost
     * @return
     */
    @PostMapping(path = "/saveByRepo")
    @ResponseBody
    public Object saveByRepo(@RequestBody  DiscussPost discussPost) {
//        final DiscussPost discussPost1 = new DiscussPost();
        discussPost.setCreateTime(new Date());
        final DiscussPost save = discussPostRepository.save(discussPost);
//        final DiscussPost save = elasticTemplate.save(discussPost);
        return  ReturnT.success(save);
//        return CommunityUitl.getJSONString(0, "发布成功",save);
    }
//    http://localhost:8081/community/discuss/saveByRepo2
//    http://localhost:8081/community/discuss/saveDiscussPost

    @Autowired
    private ElasticsearchService elasticsearchService;
    @PostMapping(path = "/saveDiscussPost")
    @ResponseBody
    public Object saveDiscussPost(@RequestBody  DiscussPost discussPost) {
//        final DiscussPost discussPost1 = new DiscussPost();
        final Integer postId =
                discussPost.getId();
        DiscussPost post = discussPostService.findDiscussPostById(postId);
//        discussPost.setCreateTime(new Date());
        elasticsearchService.saveDiscussPost(post);

        return  ReturnT.success(post);
    }

    @PostMapping(path = "/saveByRepo2")
    @ResponseBody
    public Object saveByRepo2(@RequestBody  DiscussPost2 discussPost) {
//        final DiscussPost discussPost1 = new DiscussPost();
        discussPost.setCreateTime(new Date());
        final DiscussPost2 save = discussPost2Repository.save(discussPost);

//        final DiscussPost save = elasticTemplate.save(discussPost);
        return  ReturnT.success(save);
//        return CommunityUitl.getJSONString(0, "发布成功",save);
    }
    @Resource
    DiscussPost2Repository discussPost2Repository;
    @PostMapping(path = "/saveTestData")
    @ResponseBody
    public Object saveTestData(@RequestBody  DiscussPost discussPost) {
//        final DiscussPost discussPost1 = new DiscussPost();
        discussPost.setCreateTime(new Date());
//        final DiscussPost discussPostById = discussPostService.findDiscussPostById(2);
        discussPostRepository.save( discussPostService.findDiscussPostById(2));
        final DiscussPost save =
                discussPostRepository.save(discussPostService.findDiscussPostById(3));
//        final DiscussPost save = discussPostRepository.save(discussPost);
//        final DiscussPost save = elasticTemplate.save(discussPost);
        return  ReturnT.success(save);
//        return CommunityUitl.getJSONString(0, "发布成功",save);
    }
    // 添加帖子
    @RequestMapping(path = "/add", method = RequestMethod.POST)
    @ResponseBody
    public String add(String title, String content) {
        User user = hostHolder.getUser();
        // 判断是否登录
        if (user == null) {
            return CommunityUitl.getJSONString(403, "你还没有登录！");
        }
        DiscussPost discussPost = new DiscussPost();
        discussPost.setUserId(user.getId());
        discussPost.setContent(content);
        discussPost.setTitle(title);
        discussPost.setCreateTime(new Date());
        discussPostService.addDiscussPost(discussPost);

        // 触发发帖事件
        Event event = new Event();
        event.setTopic(TOPIC_PUBLISH);
        event.setUserId(user.getId());
        event.setEntityType(ENTITY_TYPE_POST);
        event.setEntityId(discussPost.getId());
        eventProducer.fireEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, discussPost.getId());


        return CommunityUitl.getJSONString(0, "发布成功");
    }

    // 点击获取当个帖子信息
    @RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        model.addAttribute("post", post);
        // 作者
        User user = userService.findUserById(post.getUserId());
        model.addAttribute("user", user);
        // 帖子点赞数量
        long likeCount = likeService.findEntityLIkeCount(ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeCount", likeCount);
        // 帖子点赞状态
        int likeStatus = hostHolder.getUser() == null ? 0 : likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeStatus", likeStatus);


        // 评论分页信息
        page.setLimit(5);
        page.setPath("/discuss/detail/" + discussPostId);
        page.setRows(post.getCommentCount());

        // 评论: 给帖子的评论
        // 回复: 给评论的评论
        // 评论列表
        List<Comment> commentList = commentService.findCommentsByEntity(
                ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
        // 评论VO列表
        List<Map<String, Object>> commentVoList = new ArrayList<>();
        if (commentList != null) {
            for (Comment comment : commentList) {
                // 评论VO
                Map<String, Object> commentVo = new HashMap<>();
                // 评论
                commentVo.put("comment", comment);
                // 作者
                commentVo.put("user", userService.findUserById(comment.getUserId()));
                // 评论点赞数量
                likeCount = likeService.findEntityLIkeCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeCount", likeCount);
                // 评论点赞状态
                likeStatus = hostHolder.getUser() == null ? 0 : likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeStatus", likeStatus);

                // 回复列表
                List<Comment> replyList = commentService.findCommentsByEntity(
                        ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
                // 回复VO列表
                List<Map<String, Object>> replyVoList = new ArrayList<>();
                if (replyList != null) {
                    for (Comment reply : replyList) {
                        Map<String, Object> replyVo = new HashMap<>();
                        // 回复
                        replyVo.put("reply", reply);
                        // 作者
                        replyVo.put("user", userService.findUserById(reply.getUserId()));
                        // 回复目标
                        User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
                        replyVo.put("target", target);
                        // 回复点赞数量
                        likeCount = likeService.findEntityLIkeCount(ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeCount", likeCount);
                        // 回复点赞状态
                        likeStatus = hostHolder.getUser() == null ? 0 : likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeStatus", likeStatus);

                        replyVoList.add(replyVo);
                    }
                }
                commentVo.put("replys", replyVoList);

                // 回复数量
                int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("replyCount", replyCount);

                commentVoList.add(commentVo);
            }
        }

        model.addAttribute("comments", commentVoList);

        return "site/discuss-detail";
    }


    // 置顶
    @RequestMapping(path = "/top", method = RequestMethod.POST)
    @ResponseBody
    public String setTop(int id){
        discussPostService.updateType(id, 1);

        // 触发发帖事件
        Event event = new Event();
        event.setTopic(TOPIC_PUBLISH);
        event.setUserId(hostHolder.getUser().getId());
        event.setEntityType(ENTITY_TYPE_POST);
        event.setEntityId(id);
        eventProducer.fireEvent(event);

        return CommunityUitl.getJSONString(0);

    }

    // 加精华
    @RequestMapping(path = "/wonderful", method = RequestMethod.POST)
    @ResponseBody
    public String setWonderful(int id){
        discussPostService.updateStatus(id, 1);

        // 触发发帖事件
        Event event = new Event();
        event.setTopic(TOPIC_PUBLISH);
        event.setUserId(hostHolder.getUser().getId());
        event.setEntityType(ENTITY_TYPE_POST);
        event.setEntityId(id);
        eventProducer.fireEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUitl.getJSONString(0);

    }

    // 删除
    @RequestMapping(path = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String setDelete(int id){
        discussPostService.updateStatus(id, 2);

        // 触发删帖事件
        Event event = new Event();
        event.setTopic(TOPIC_DELETE);
        event.setUserId(hostHolder.getUser().getId());
        event.setEntityType(ENTITY_TYPE_POST);
        event.setEntityId(id);
        eventProducer.fireEvent(event);

        return CommunityUitl.getJSONString(0);

    }


}

